diff --git a/changes/1.5.0.md b/changes/1.5.0.md index 657378801b24ae75ee24a3f0c6f7cbcfe79f6638..2c26f97f473f43a075053e171a3f85f634bcfd1f 100644 --- a/changes/1.5.0.md +++ b/changes/1.5.0.md @@ -36,7 +36,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单 - [[#3408](https://github.com/seata/seata/pull/3408)] 修复jar运行模式, 当第三方依赖分开打包时, this.getClass().getClassLoader()是null, 会报空指针异常 - [[#3431](https://github.com/seata/seata/pull/3431)] 修复在读取配置时Property Bean可能还未初始化 - [[#3413](https://github.com/seata/seata/pull/3413)] 修复回滚到savepoint以及releaseSavepoint的逻辑 - + - [[#3451](https://github.com/seata/seata/pull/3451)] 修复当不使用本地事务且设置自动提交为true时,全局锁竞争失败会使得rm退出全局事务,导致全局锁在rm重试时失效,数据被脏写 ### optimize: @@ -85,6 +85,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单 - [xingfudeshi](https://github.com/xingfudeshi) - [MentosL](https://github.com/MentosL) - [lian88jian](https://github.com/lian88jian) + - [litianyu1992](https://github.com/litianyu1992) 同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。 diff --git a/changes/en-us/1.5.0.md b/changes/en-us/1.5.0.md index 262735cd243faf5fd0e44d3e715e591c33d81dc6..d6f4f6cf6e70e1bc50b41d73cfbc48fe471183aa 100644 --- a/changes/en-us/1.5.0.md +++ b/changes/en-us/1.5.0.md @@ -23,6 +23,7 @@ - [[#3348](https://github.com/seata/seata/pull/3348)] support redis sentinel mode - [[#2667](https://github.com/seata/seata/pull/2667)] support password decryption - [[#3427](https://github.com/seata/seata/pull/3427)] add distributed lock interface + - [[#3443](https://github.com/seata/seata/pull/3443)] send the `seata-server` log to `logstash` or `kafka` ### bugfix: @@ -35,7 +36,7 @@ - [[#3408](https://github.com/seata/seata/pull/3408)] run with jar file and not package third lib into jar file, this.getClass().getClassLoader() will be null - [[#3431](https://github.com/seata/seata/pull/3431)] fix property bean may not be initialized when reading configuration - [[#3413](https://github.com/seata/seata/pull/3413)] fix the logic of rollback to savepoint and release to savepoint - - [[#3443](https://github.com/seata/seata/pull/3443)] send the `seata-server` log to `logstash` or `kafka` + - [[#3451](https://github.com/seata/seata/pull/3451)] fix set auto-commit to true when local transactions are not being used. Failure to compete for a lock causes the global transaction to exit, invaliding the global row lock and dirty writing of the data. ### optimize: @@ -82,6 +83,7 @@ - [xingfudeshi](https://github.com/xingfudeshi) - [MentosL](https://github.com/MentosL) - [lian88jian](https://github.com/lian88jian) + - [litianyu1992](https://github.com/litianyu1992) Also, we receive many valuable issues, questions and advices from our community. Thanks for you all. diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionContext.java b/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionContext.java index 4c6c222a0fc4f1112e9f70d4b23debf9848f7fec..a5fd74cbf9c58f5fb4059f03bcbf516bce93e7ff 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionContext.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionContext.java @@ -52,6 +52,7 @@ public class ConnectionContext { private Long branchId; private boolean isGlobalLockRequire; private Savepoint currentSavepoint = DEFAULT_SAVEPOINT; + private boolean autoCommitChanged; /** * the lock keys buffer @@ -238,6 +239,24 @@ public class ConnectionContext { this.branchId = branchId; } + /** + * is seata change targetConnection autoCommit + * + * @return the boolean + */ + public boolean isAutoCommitChanged() { + return this.autoCommitChanged; + } + + /** + * set seata change targetConnection autoCommit record + * + * @param autoCommitChanged the boolean + */ + public void setAutoCommitChanged(boolean autoCommitChanged) { + this.autoCommitChanged = autoCommitChanged; + } + /** * Reset. @@ -258,6 +277,7 @@ public class ConnectionContext { savepoints.clear(); lockKeysBuffer.clear(); sqlUndoItemsBuffer.clear(); + this.autoCommitChanged = false; } /** diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionProxy.java b/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionProxy.java index 6b34f2c6d72effa37bc677400ac50a21e5336079..5e5c362578c3d0a1117c70f03f5af196f1c6a561 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionProxy.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionProxy.java @@ -186,7 +186,7 @@ public class ConnectionProxy extends AbstractConnectionProxy { return null; }); } catch (SQLException e) { - if (targetConnection != null && !getAutoCommit()) { + if (targetConnection != null && !getAutoCommit() && !getContext().isAutoCommitChanged()) { rollback(); } throw e; @@ -280,6 +280,16 @@ public class ConnectionProxy extends AbstractConnectionProxy { context.reset(); } + /** + * change connection autoCommit to false by seata + * + * @throws SQLException + */ + public void changeAutoCommit() throws SQLException { + getContext().setAutoCommitChanged(true); + setAutoCommit(false); + } + @Override public void setAutoCommit(boolean autoCommit) throws SQLException { if ((context.inGlobalTransaction() || context.isGlobalLockRequire()) && autoCommit && !getAutoCommit()) { diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/AbstractDMLBaseExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/AbstractDMLBaseExecutor.java index 04302c7d419ba9a5a3f018bb9032e591baaccb3a..d42d365bc66191f9bbabd509be0387444acd6d70 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/AbstractDMLBaseExecutor.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/AbstractDMLBaseExecutor.java @@ -135,7 +135,7 @@ public abstract class AbstractDMLBaseExecutor<T, S extends Statement> extends Ba protected T executeAutoCommitTrue(Object[] args) throws Throwable { ConnectionProxy connectionProxy = statementProxy.getConnectionProxy(); try { - connectionProxy.setAutoCommit(false); + connectionProxy.changeAutoCommit(); return new LockRetryPolicy(connectionProxy).execute(() -> { T result = executeAutoCommitFalse(args); connectionProxy.commit();