事务是一系列持久化动作的集合,如果事务成功,则更改保存;如果事务失败,则
事务回滚;无论处于任何一种状态,数据保持干净与一致。
事务具有隔离性,原子性,耐久性,并发操作的正确性。
普通JDBC事务
事务在JDBC实现是通过下面方式:
setAutoCommit(false);
commit();
rollback();
这种方式是一种低伸缩性(scalability)架构,因为每个事务要绑定一个JDBC连接,也就是一个Connection对象。
伸缩性优化
JavaEE的JTA+JTA兼容性运行时环境解决此类问题,它能够提供所有JDBC事务的功能同时拥有以下几个新的特点:
- 支持多个数据库上的数据进行操作在同一事务出现
- 数据库连接对象管理(申请和释放,高伸缩性来自这个特点)
目前为止利用Hibernate事务接口你可能这样写:
Session session=null;
Transaction transaction=null;
try{
session=sessionFactory.openSession();
transaction=session.beginTransaction();
//do something
transaction.commit();
}catch(RuntimeException ex){
try{
tx.rollback();
}catch(RuntimeException ex){
log.error("can't roolback",ex);
}
}
session.close();
Hibernate底层通常使用PreparedStatement
来执行SQL,Session对象通常保持着一个数据库连接(Connection
对象),不过和数据库Connection对象一样保持一个连接,为什么使用Hibernate来增加编写复杂性?
原因就在于需要一个开关(一些配置)你就可以利用Hibernate来使用JTA,在JavaEE应用服务器下,你可以实现多数据源事务操作。实际上这些配置是将Hiberante配置为JTA模式。
//切换JTA模式
hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory;
//这个设置JavaEE环境(JTA实现环境)
hibernate.transaction.manager_look_up_class=org.hibernate.transaction.JBossTransaction-ManagerLookup
但是还需要一个额外的步骤就是JNDI配置一个全局注册项,自己Google集成JTA
配置完这些之后,Hibernate不再是连接管理者,而是JavaEE环境(运行时容器),连接通过JNDI来获取。JNDI配置你的数据源。
现在所有都配置好了,看一下多个数据库事务处理
多数据库事务处理
多数据库处理先使用JNDI来查找与Hibernate等价的JTA 的UserTranscation对象。
UserTranscation utx=(UserTransaction)new InitialContext().lookup("yourregistryURL");
Session first=null;
Session second=null;
try{
utx.begin();
first=firstDataBase.openSession();
second=secondDataBase.openSession();
//do something
//注意这里
first.flush();
second.flush();
utx.commit();
}catch(RuntimeException e){
try{
tx.rollback();
}catch(RuntimeException ex){
log.error("can't roolback",ex);
}
}finally{
first.close();
second.close();
}
考虑到同步化,Session通常是惰性的,也就是直到事务关闭,Session才会发射所有的DML语句到数据库,flush()
方法负责释放。
使用以下配置来简化代码:
hibernate.transaction.flush_before_completion=true;
hibernate.transaction.auto_close_session=true;
以上的语句flush()
和close()
方法就都不用执行了!
综合分析一下数据库连接的变化状态:
原来Session保持数据库连接的粒度对比
方式 | 粒度 |
普通JDBC | 事务粒度 |
JTA配置状态 | 语句(Statement)粒度 |