线程内事务;应用内事务(跨线程、跨会话);跨应用事务;分布式事务
最后更新:2024-09-14 23:12:03
|
状态:未完成
- 线程内事务
- 应用内事务(跨线程、跨会话)
- 跨应用事务
- 分布式事务
默认的事务是基于线程变量实现的,参考【线程内事务说明】
8.7.2及之后开始支持跨线程事务,在整个应用内有效。参考【跨线程事务说明】
应用场景:
开启或提交事务 不在同一线程内
如果依赖了anyline-environment-spring-data-jdbc需要启用DefaultEnvironmentWorker.start();覆盖spring事务管理器
以下代码要特别注意的是: 各个线程之间没有任何联系,编码环节 也分不出谁先谁后,调用的有可能是同一个方法,也有可能是不同的方法
先看第1个线程 假设是用户A在IP1调用的 这里启动了一个 name = tx1 的事务,这个tx1是用来唯一标识
例如,用流程ID来生成这个事务name实现同 同一个流程的不同线程在同一个事务中
再强调一下:这里的t1,t2只是个名称,没有先后,不一定是先调用t1有可能是先调用的t2
public static void t1() throws Exception{ //跨线程事务 TransactionDefine define = new DefaultTransactionDefine(); define.setName("tx1");//假设这个tx1就是流程ID 如果tx1事务存在默认会加入这个事务,如果不存在就新开启一个tx1事务,如果不提供则随机生成 define.setMode(TransactionDefine.MODE.APPLICATION);//设置有效范围 要设置整个应用内有效,要不然线程结束后就找不到了。 TransactionState state = TransactionProxy.start(define); //启动事务后,这个事务就会从连接池中获取连接,也就是与这个连接绑定了。后面提交这个事务时就知道提交哪个连接的事务了 DataRow row = new DataRow(); row.put("CODE", 1); ServiceProxy.insert("CRM_USER", row); String name = state.getName(); //这样可以返回事务name }第2个线程 假设是用户B在IP2调用的,因为线程间没有任务关联,所以要用相同的事务ID才能联系到一块
public static void t2() { TransactionDefine define = new DefaultTransactionDefine(); define.setName("tx1"); //使用同一个name启动事务 如果tx1事务存在默认会加入这个事务,如果不存在就新开启一个tx1事务 // 再强调一下 这里不用管t1()方法 中有没有启动过tx1事务,t1()方法可能还没调用过 define.setMode(TransactionDefine.MODE.APPLICATION); TransactionState state = TransactionProxy.start(define); DataRow row = new DataRow(); row.put("CODE", 2); ServiceProxy.insert("CRM_USER", row); //根据业务逻辑 两个操作一块提交或回滚 TransactionProxy.rollback(state); //TransactionProxy.commit(state); }