- #beginInternal()
- /**
- * 开启柔性
- *
- * @param conn 分片连接
- * @param type 事务类型
- * @throws SQLException
- */
- protected final void beginInternal(final Connection conn, final SoftTransactionType type) throws SQLException {
- // TODO 判断如果在传统事务中, 则抛异常
- Preconditions.checkArgument(conn instanceof ShardingConnection, "Only ShardingConnection can support eventual consistency transaction.");
- // 设置执行错误, 不抛出异常
- ExecutorExceptionHandler.setExceptionThrown(false);
- connection = (ShardingConnection) conn;
- transactionType = type;
- // 设置自动提交状态
- previousAutoCommit = connection.getAutoCommit();
- connection.setAutoCommit(true);
- // 生成事务编号
- // TODO 替换 UUID 为更有效率的 id 生成器
- transactionId = UUID.randomUUID().toString();
- }
调用
ExecutorExceptionHandler.setExceptionThrown(false)
设置执行 SQL 错误时, 也不抛出异常.
对异常处理的代码: ExecutorExceptionHandler#setExceptionThrown() https://github.com/dangdangdotcom/sharding-jdbc/blob/884b38f4c2402e31464d15b444f4b405e07fe211/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/threadlocal/ExecutorExceptionHandler.java#L59
对于其他 SQL, 不会因为 SQL 错误不执行, 会继续执行
对于上层业务, 不会因为 SQL 错误终止逻辑, 会继续执行. 这里有一点要注意下, 上层业务不能对该 SQL 执行结果有强依赖, 因为 SQL 错误需要重试达到数据最终一致性
对于最大努力型事务 ( TCC 暂未实现 ), 会对执行错误的 SQL 进行重试
调用
connection.setAutoCommit(true);
, 设置执行自动提交. 使用最大努力型事务时, 上层业务执行 SQL 会马上提交, 即使调用
Connection#rollback()
也是无法回滚的, 这点一定要注意.
- #end()
- /**
- * 结束柔性事务.
- */
- public final void end() throws SQLException {
- if (connection != null) {
- ExecutorExceptionHandler.setExceptionThrown(true);
- connection.setAutoCommit(previousAutoCommit);
- SoftTransactionManager.closeCurrentTransactionManager();
- }
- }
- // SoftTransactionManager.java
- /**
- * 关闭当前的柔性事务管理器.
- */
- static void closeCurrentTransactionManager() {
- ExecutorDataMap.getDataMap().put(TRANSACTION, null);
- ExecutorDataMap.getDataMap().put(TRANSACTION_CONFIG, null);
- }
事务结束后, 一定要记得调用 #end() 清理线程变量. 否则, 下次请求使用到该线程, 会继续在这个柔性事务内.
来源: http://www.suo.im/4FKuzq