hibernate3保存對象爲什麼必須使用事務

    今天在csdn上看到一個特別有趣的話題,hibernate3爲什麼必須使用事務才能保存對象,我相信這個問題對很多人來說都非常困惑包括我自己,於是掛上hibernate源碼,一直跟蹤最底層,也沒發現什麼,然而正是因爲沒用發現什麼才點醒了我,回憶多年前使用經典jdbc的場景,那時候使用事務必須自己手工控制conn.setAutoCommit(false); 纔行。而現在如果我們要正常使用hibernate3保存對象的話要使用事務處理纔行:

	public static void main(String[] args) throws Exception {
		SessionFactory sf = HibernateSessionFactory.getSessionFactory();
		Session session = sf.openSession();
		session.beginTransaction();
		User u = new User();
		u.setName("aaa");
		session.save(u);
		session.getTransaction().commit();
	}
使用spring聲明式事務本質上和上面是一樣的,spring只不過是利用了動態代理而已。 從上面代碼可以看到beginTransaction非常像很久以前我們寫的conn.setAutoCommit(false); 而session.getTransaction().commit();則是對應conn.commit();那會不會是因爲conn已經默認是false了呢
System.out.println(session.connection().getAutoCommit());//經測試果然如此。經測試下面代碼可以成功保存對象。
		SessionFactory sf = HibernateSessionFactory.getSessionFactory();
		Session session = sf.openSession();
		System.out.println(session.connection().getAutoCommit());
		session.connection().setAutoCommit(true);
		User u = new User();
		u.setName("aaa");
		session.save(u);

只要修改conn默認的提交方式就可以了,爲了進一步驗證這個問題其實和hibernate是無關的,寫了如下測試代碼,同樣可以正常的保存對象。

public static void main(String[] args) throws Exception {
		Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
		Connection conn = DriverManager.getConnection(
				"jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs",
				"sa", "11111111");
		SessionFactory sf = HibernateSessionFactory.getSessionFactory();
		Session session = sf.openSession(conn);
		System.out.println(session.connection().getAutoCommit());
		// session.connection().setAutoCommit(true);
		User u = new User();
		u.setName("aaa");
		session.save(u);
	}

 

其實我覺得必須使用事務才能保存對象是大家對hibernate的誤解,目前流行的數據庫連接池默認的情況下都是conn自動提交爲false的。很多連接池還可以靈活的配置,我們還是要還hibernate清白的。這是取決於數據庫連接池的配置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章