我的测试代码如下:事务隔离级别为repeatable read
//來自《精通Hibernate》
package com.test;
import java.util.ArrayList;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.model.Account;
public class TestHql3 extends Thread{
private String transactionType;
private Log log;
private static Session session = HibernateSessionFactory.getSession();
public TestHql3(String transactionType, Log log) {
super();
this.transactionType = transactionType;
this.log = log;
}
public void run() {
try {
if (transactionType.equals("withdraw"))
withdraw();
else
transferCheck();
} catch (Exception e) {
e.printStackTrace();
}
}
public void withdraw() throws Exception {
Transaction tx = session.beginTransaction();
log.write("withdraw():開始事務");
Thread.sleep(500);
Account account = (Account)session.get(Account.class, new Integer(1));
log.write("withdraw():查詢到存款餘額為:balance="+account.getBalance());
Thread.sleep(500);
account.setBalance(account.getBalance()-100);
log.write("withdraw():取出100元,把存款餘額改為:"+account.getBalance());
log.write("withdraw:提交事務");
tx.commit();
Thread.sleep(500);
}
public void transferCheck() throws Exception {
//Thread.sleep(10);-----------------------------------------------------------
Transaction tx = session.beginTransaction();
log.write("transferCheck():開始事務");
Thread.sleep(500);
Account account = (Account)session.get(Account.class, new Integer(1));
log.write("transferCheck():查詢到餘額為:balance = "+account.getBalance());
Thread.sleep(500);
account.setBalance(account.getBalance()+100);
log.write("transferCheck():匯入100元,把餘款改為:"+account.getBalance());
log.write("transferCheck():提交事務");
tx.commit();
Thread.sleep(500);
}
public void registerAccount() throws Exception {
}
public static void main(String args[]) throws Exception {
Log log = new Log();
Thread withdrawThread = new TestHql3("withdraw",log);
Thread transferCheckThread = new TestHql3("thransferCheck",log);
withdrawThread.start();
transferCheckThread.start();
while(withdrawThread.isAlive()||transferCheckThread.isAlive())
Thread.sleep(100);
log.print();
session.close();
}
}
class Log {
private ArrayList<String> logs = new ArrayList<String>();
synchronized void write(String text) {
logs.add(text);
}
public void print() {
for (String s : logs) {
System.out.println(s);
}
}
}
输出:
1.当标记为红色的哪行为Thread.sleep(0)是一切正常:
transferCheck():開始事務
withdraw():開始事務
withdraw():查詢到存款餘額為:balance=900
transferCheck():查詢到餘額為:balance = 900
withdraw():取出100元,把存款餘額改為:800
transferCheck():匯入100元,把餘款改為:1000
withdraw:提交事務
transferCheck():提交事務
2.当标记为红色的哪行为Thread.sleep(5),输出出错:
java.lang.NullPointerException
at org.hibernate.jdbc.AbstractBatcher.closePreparedStatement(AbstractBatcher.java:471)
at org.hibernate.jdbc.AbstractBatcher.closeStatement(AbstractBatcher.java:218)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:198)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.test.TestHql3.withdraw(TestHql3.java:44)
at com.test.TestHql3.run(TestHql3.java:24)
withdraw():開始事務
transferCheck():開始事務
withdraw():查詢到存款餘額為:balance=1000
transferCheck():查詢到餘額為:balance = 1000
withdraw():取出100元,把存款餘額改為:900
transferCheck():匯入100元,把餘款改為:1100
withdraw:提交事務
transferCheck():提交事務
3.当标记为红色的哪行为Thread.sleep(10),输出出错:
java.lang.ArrayIndexOutOfBoundsException: 1
at org.hibernate.util.IdentityMap.entryArray(IdentityMap.java:199)
at org.hibernate.util.IdentityMap.concurrentEntries(IdentityMap.java:59)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:113)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.test.TestHql3.transferCheck(TestHql3.java:63)
at com.test.TestHql3.run(TestHql3.java:26)
java.lang.ArrayIndexOutOfBoundsException: 1
at org.hibernate.util.IdentityMap.entryArray(IdentityMap.java:199)
at org.hibernate.util.IdentityMap.concurrentEntries(IdentityMap.java:59)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:113)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.test.TestHql3.withdraw(TestHql3.java:44)
at com.test.TestHql3.run(TestHql3.java:24)
withdraw():開始事務
transferCheck():開始事務
withdraw():查詢到存款餘額為:balance=1000
transferCheck():查詢到餘額為:balance = 1000
transferCheck():匯入100元,把餘款改為:1100
withdraw():取出100元,把存款餘額改為:900
transferCheck():提交事務
withdraw:提交事務
4.当标记为红色的哪行为Thread.sleep(100),输出出错://这个应该是嵌套事务出错
org.hibernate.TransactionException: Transaction not successfully started
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:100)
at com.test.TestHql3.transferCheck(TestHql3.java:63)
at com.test.TestHql3.run(TestHql3.java:26)
withdraw():開始事務
transferCheck():開始事務
withdraw():查詢到存款餘額為:balance=1100
transferCheck():查詢到餘額為:balance = 1100
withdraw():取出100元,把存款餘額改為:1000
withdraw:提交事務
transferCheck():匯入100元,把餘款改為:1100
transferCheck():提交事務