线程内事务;应用内事务(跨线程、跨会话);跨应用事务;分布式事务

最后更新: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);
}
首页 最近更新 搜索 提交 回复