jTransactions声明式事务工具

联合创作 · 2023-09-30

jTransactions

开源协议: Apache 2.0

jTransactions是一个声明式事务工具,目的是将Java的事务功能独立出来,做成一个单独的库来使用

jTransactions目前仅包含两个实现: TinyTX和SpringTx。

TinyTX是一个微型的只有4个文件组成的、具有简单功能的声明式事务服务,是Spring事务之外一个小巧的选择。

SpringTx是对Spring声明式事务的包装,SpringTx适用于开发复杂的大型项目(例如使用到了嵌套事务),使用SpringTx需要在项 目中添加对Spring库的依赖。原则上,除了TinyTx外,jTransactions不重新开发自已的事务实现,其它事务服务如Spring事务、JTA事务、EJB容器事务等将只做简单的包装容纳进这个项目,jTransactions与具体实现的关系正如common-log与Log4J的关系,一个是接口,一个是具体的实现。

jTransactions是一个可扩充的架构,将来可能会不断有新的事务实现添加进来。jTransactions运行环境为Java6或以上。

如何引入项目?

方式一:手工下载jtransactions-1.0.0.jar并放置于项目的类目录。

方式二:在项目的pom.xml文件中加入如下行:

   <dependency>  
      <groupId>com.github.drinkjava2</groupId>  
      <artifactId>jtransactions</artifactId>  
      <version>1.0.0</version>  
   </dependency>

注:

  1. 如果只使用TinyTX,以上配置就可以了。如果使用SpringTx, 还需要在pom.xml中添加对Spring-tx的依赖。

  2. jTransactions还必须与一个支持AOP Alliance接口规范的AOP工具如Spring或jBeanBox配合使用,因为声明式事务的基本原理是对方法的拦截,必须有一个AOP工具来实现这个功能。

  3. jTransactions还必须一个JDBC工具配合使用,如纯JDBC、JdbcTemplate、DbUtils-pro或jSqlBox等。

介绍

jTransactions分为连接管理器ConnectionManager和CommonTx两个接 口,ConnectionManager接口的实现类的两个方法,getConnection和releaseConnection,如使用纯JDBC, 必须用这两个方法来获取和释放连接。如使用一些工具类如JdbcTemplate、DbUtils-Pro和jSqlBox等,其内部获取和释放连接已经 调用这两个方法,所以无需关心连接的获取和释放。 CommonTx实现类是由框架来提供,用户不必关心实现细节,只需要利用AOP工具配置使用 即可。具体使用见下面示例。

一. TinyTx和SpringTx声明式事务演示 TinyTx是一个核心只有4个类组成的微型的声明式事务实现,它旨在小项目中替代复杂的Spring声明式事务,在精简尺寸的同时达到降低学习成本、提高项目的掌控感(即可维护性)的目的。其功能比较简单,只要发现有未捕获的任何异常即回滚事务,可用于小型项目的开发。SpringTx是对Spring 事明式事务的包装,功能完备,适用于大型项目。

以下是演示jTransactions与jBeanBox搭配的用法,这个示例实现了在运行期动态在TinyTx和SpringTx两个事务提供者之间切换。

public class TxTester {
	private static Class<?> tx = TinyTx.class;
	private static ConnectionManager cm = TinyTxConnectionManager.instance();

	public static class TxBox extends BeanBox {
		{
			this.setConstructor(tx, BeanBox.getBean(DataSourceBox.class), Connection.TRANSACTION_READ_COMMITTED);
		}
	}

	TinyJdbc db = new TinyJdbc((DataSource) BeanBox.getBean(DataSourceBox.class), cm);

	@AopAround(TxBox.class)
	public void tx_Insert1() {
		db.executeSql("insert into users (id) values('123')");
	}

	@AopAround(TxBox.class)
	public void tx_Insert2() {
		db.executeSql("insert into users (id) values('456')");
		Assert.assertEquals(2L, db.queryForObject("select count(*) from users"));
		System.out.println("Now have 2 records in users table, but will roll back to 1");
		System.out.println(1 / 0);
	}

	public void doTest() {
		try {
			db.executeSql("drop table users");
		} catch (Exception e) {
		}
		db.executeSql("create table users (id varchar(40))engine=InnoDB");
		Assert.assertEquals(0L, db.queryForObject("select count(*) from users"));
		try {
			tx_Insert1();// this one inserted 1 record
			tx_Insert2();// this one did not insert, roll back
		} catch (Exception e) {
			System.out.println("div/0 exception found, tx_Insert2 should roll back");
		}
		Assert.assertEquals(1L, db.queryForObject("select count(*) from users"));
	}

	@Test
	public void userTinyTx() {
		TxTester tester = BeanBox.getBean(TxTester.class);
		tester.doTest();
		BeanBox.defaultContext.close();// Release DataSource Pool
	}

	@Test
	public void testSprintTx() {
		tx = SpringTx.class;
		cm = SpringTxConnectionManager.instance();
		TxTester tester = BeanBox.getBean(TxTester.class);
		tester.doTest();
		BeanBox.defaultContext.close();// Release DataSource Pool
	}
}

以上即为jTransactions全部文档,如有疑问,请下载并运行单元测试示例或查看源码。

后记:关于这个项目,本来我没打算开发它,在开发DbUtils-Pro和jSqlBox项目时,需要找一个小巧点的独立的事务工具,原以为这方面 的开源项目会有一大把,但很遗憾的是,我一个也没有找到!只好自已从头写一个TinyTx,水平很烂,但是勉强能够工作了。 至于为什么不直接用Spring事务是因为它太大了、太占内存、太复杂,太多标签、太多依赖,绑死在Spring环 境中无法抽取出来,使用Spring的声明式事务要加上一堆库依赖,其中居然有JdbcTemplate库,事务服务依赖于JDBC工具,难道这就是 Spring号称的反转依赖不成? 至于jfinal的事务服务,看了一下源码,比较简单,但是依然写死在了Jfinal环境中,不能抽取出来给其它持久层工具使用,而且它没有和数据源绑 定。jTransaction的架构是开放式的,甚至充许在运行期动态切换事务服务。今后如果有人发现了什么比较好用的事务工具也可以告诉我,我可将它包 含到这个项目中来。目前下一步的开发打算是将一个现成的JTA事务实现集成进来。

浏览 4
点赞
评论
收藏
分享

手机扫一扫分享

编辑
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

编辑
举报