MySQL的事务、JDBC事务操作:
详细见这篇文章:比较详细
http://www.cnblogs.com/xuyiqing/p/8430214.html
如何在hibernate中配置隔离级别:
再核心配置文件中:
<!-- 指定hibernate操作数据库时的隔离级别 #hibernate.connection.isolation 1|2|4|8 0001 1 读未提交 0010 2 读已提交 0100 4 可重复读 1000 8 串行化 --> <property name="hibernate.connection.isolation">4</property>
这里是二进制,转换成十进制就是1,2,4,8
项目中管理事务:
没有学习hibernate框架以前,在项目中,开启事务在业务层(service),执行之后提交或回滚
而在hibernate框架中,也是这样,操作数据库需要用到的session对象,一定保证,service层和dao层的session是同一个
类似servlet项目中需要确保service层和dao层的connection对象一致,当时用到了绑定线程
(这是以前sevlet项目中的一个工具类,可以浏览下对比)
package utils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class DataSourceUtils { private static DataSource dataSource = new ComboPooledDataSource(); private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); // 直接可以获取一个连接池 public static DataSource getDataSource() { return dataSource; } // 获取连接对象 public static Connection getConnection() throws SQLException { Connection con = tl.get(); if (con == null) { con = dataSource.getConnection(); tl.set(con); } return con; } // 开启事务 public static void startTransaction() throws SQLException { Connection con = getConnection(); if (con != null) { con.setAutoCommit(false); } } // 事务回滚 public static void rollback() throws SQLException { Connection con = getConnection(); if (con != null) { con.rollback(); } } // 提交并且 关闭资源及从ThreadLocall中释放 public static void commitAndRelease() throws SQLException { Connection con = getConnection(); if (con != null) { con.commit(); // 事务提交 con.close();// 关闭资源 tl.remove();// 从线程绑定中移除 } } // 关闭资源方法 public static void closeConnection() throws SQLException { Connection con = getConnection(); if (con != null) { con.close(); } } public static void closeStatement(Statement st) throws SQLException { if (st != null) { st.close(); } } public static void closeResultSet(ResultSet rs) throws SQLException { if (rs != null) { rs.close(); } } }
在hibernate框架中,原理是一样的,绑定线程
但是,只需要在核心配置文件中配置:
<!-- 指定session与当前线程绑定 --> <property name="hibernate.current_session_context_class">thread</property>
代码只需一行:
SessionFactory sf = new Configuration().configure().buildSessionFactory(); sf.getCurrentSession();
简单的测试即可理解:
package demo; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.Test; import utils.HibernateUtils; //测试getCurrentSession public class Demo { @Test //返回同一个与线程绑定的session public void fun1(){ Session session1 = HibernateUtils.getCurrentSession(); Session session2 = HibernateUtils.getCurrentSession(); System.out.println(session1==session2);//true } @Test //返回不同的session public void fun2(){ Session session1 = HibernateUtils.openSession(); Session session2 = HibernateUtils.openSession(); System.out.println(session1==session2);//false } }
补上工具类:
package utils; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtils { private static SessionFactory sf; static{ //1 创建,调用空参构造 Configuration conf = new Configuration().configure(); //2 根据配置信息,创建 SessionFactory对象 sf = conf.buildSessionFactory(); } //获得session => 获得全新session public static Session openSession(){ //3 获得session Session session = sf.openSession(); return session; } //获得session => 获得与线程绑定的session public static Session getCurrentSession(){ //3 获得session Session session = sf.getCurrentSession(); return session; } }
注意:
通过getCurrentSession方法获得的session对象,事务提交时候,会自动关闭session,不要手动关闭,否则会有异常