精通Hibernate——数据库的事务与声明事务边界

数据库事务必须具备ACID特征,分别是原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)
声明事务包含以下内容:
1、事务的开始边界
2、事务的正常结束边界(commit):提交事务
3、事务的异常结束边界(rollback):撤销事务,使数据回到事务前的状态
数据库系统支持以下两种事务
1、自动提交模式:每个sql语句都是一个独立的事务,当数据库系统执行完一个sql语句后,就会自动提交事务
2、手动提交模式:必须由数据库的客户程序显式的指定事务的开始和结束边界
在Mysql中,数据库表分为innodb,bdb和Myisam。其中InnoDB和BDB支持事务,Myisam不支持事务
在Mysql.exe程序中声明事务
每启动一个mysql.exe程序,就会得到一个单独的数据库连接。而每个数据库连接都有一个全局@@autocommit,表示当前事务模式,他有两个值
0:表示手工提交模式
1:默认值,自动提交模式
如果要查看当前事务模式,可以使用以下sql命令:

select @@autocommit;

修改事务模式

set autocommit = 0;

通过JDBC API声明事务边界
在JDBC API中,java.sql.Connection类代表一个数据库连接,以下程序用于创建一个Connection类的实例:

//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//注册Mysql驱动程序
DriverManager.registerDriver(new com.mysql.jdbc.Driver);
//指定连接数据库的URL、用户名和口令
String dbUrl = "jdbc:mysql://localhost:3306/testDb?useUnicode=true&characterEncoding=GB2312";
String dbUser = "root";
String dbPwd = "123456";
//建立数据库连接
Connection conn = java.sql.DriverManager.getConnection(dbUrl,dbUser,dbPwd);

Connection类提供了以下用于控制事务的方法:
setAutoCommit(boolean autoCommit);设置是否自动提交事务
commit();提交事务
rollback();回滚事务
通过Hibernate API声明事务边界
Hibernate封装了JDBC API和JTA API。当应用程序通过Hibernate API声明事务时,必须先获得一个Session实例,每个session实例都包含一个数据库连接。从SessionFactory中获得一个Session实例有两种方式:
1、调用SessionFactory的不带参数的openSession方法

Session session = sessionFactory.openSession();

以上openSession()方法从数据库连接池中获得连接,Session会自动把这个连接设为手动提交事务模式
2、调用SessionFactory的带参数的openSession(Connection connection)方法

java.sql.Connection con = java.sql.DriverManager.getConnection(dbUrl,dbUser,dbPwd);
//设置手动提交事务模式
con.setAutoCommit(false);
Session session = sessionFactory.openSession(con);

以上openSession(Connection connection)方法由应用程序提供数据库连接,因此应用程序必须负责设置数据库连接事务的提交方式。这种方式允许应用程序绕过Hibernate API,直接通过JDBC API访问数据库,此时Hibernate无法跟踪同一个事务中所有的sql,而且Hibernate无法使用二级缓存,因此尽量避免使用这种方式。
在Hibernate API中,Session和Transaction类提供了以下声明事务边界的方法。
声明事务边界开始

Transaction tx = session.beginTransaction();

提交事务

tx.commit();

撤销事务

tx.rollback();

尽管一个Session可以对应多个事务,但是应该优先考虑让一个Session只对应一个事务,当一个事务结束或者撤消后,就关闭session。
关于Transaction和Session的关系,有以下指的注意的地方
1、Transaction的rollback以及Session的close方法都会抛出HibernateException,在实际应用中处理这种异常,可以对底层的HibernateException进行封装,向高层客户程序隐藏撤销事务或关闭Session时出现的底层异常细节。
2、不管事务成功与否,最后都应该调用Session的close方法来关闭session
3、即使事务中仅包含只读操作,也应该在事务执行成功后提交事务,并且在事务执行失败时撤销事务,因为在提交或撤销事务时,数据库系统会释放事务所占用的资源,这有利于提高数据库的运行性能。
4、一个Session可以包含多个Transaction实例。
5、如果在执行Session的一个事务时出现了异常,就必须立即关闭这个Session,不能再利用这个Session来执行其他事务
例如以下代码把两个事务各自放在单独的try-catch代码块中,即使第一个事务执行失败仍然会执行第二个事务

try{
    try{
        tx1 = session.beginTransaction();
        ...
        tx1.commt();
    }catch(Exception e){
        if(tx1!=null) tx1.rollback();
    }
    try{
        tx2 = session.beginTransaction();
        ...
        tx2.commt();
    }catch(Exception e){
        if(tx2!=null) tx2.rollback();
    }
}finally{
    session.close();
}

这种做法是不可取的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值