`
daniel_ic
  • 浏览: 2490 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Thread.sleep对事务的影响?

阅读更多

我的测试代码如下:事务隔离级别为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():提交事務

 

分享到:
评论

相关推荐

    spring boot注解事务+多线程

    Thread.sleep(5000); // 模拟耗时操作 return new AsyncResult("Task completed"); } } ``` 在这个例子中,`longRunningTask`方法将在后台线程中执行,不会阻塞主线程,提高了程序的响应速度。 同时,Spring ...

    ActiveMQ_Demo

    Thread.sleep(1000); TextMessage msg = (TextMessage) consumer.receive(); if(msg!=null) { msg.acknowledge(); System.out.println(Thread.currentThread().getName() +": Consumer:我是消费者,我...

    JAVA核心知识点整理(有效)

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................

    Java实现的mysql事务处理操作示例

    Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } ps2 = conn.prepareStatement("insert into t_user (username,pwd) values (?,?)"); ps2.setObject(1, "李四"); ps2.set...

    Java面试总结,Redis宕机数据丢失解决方案,看完这篇彻底明白了.docx

    * Thread.sleep()使线程进入休眠状态,Thread.yield()使线程让出CPU的执行权 三、Java数据结构和算法 1. ArrayList和LinkedList的区别 * ArrayList基于数组实现,LinkedList基于链表实现 2. HashSet和...

    java多线程面试相关问题

    - `Thread.sleep()`:让当前线程暂停执行指定时间,释放CPU但保留对象锁,期间线程可以被中断,结束后自动恢复。 - `Thread.suspend()`:已过时,会导致线程停滞并保留对象锁,可能引发死锁,不应使用。 - `...

    java 一个死锁的例子

    Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resource2) { System.out.println("Thread 1 acquired resource 2"); } } }); Thread thread2 = new ...

    Java Thread Programming

    Java提供了多种线程控制方法,如start()用于启动线程,run()是线程的主要执行体,join()使当前线程等待该线程终止,sleep()使线程暂停执行一段时间,yield()让当前线程暂停,让其他线程有机会运行,synchronized...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【Dubbo】服务上线怎么不影响旧版本? 174 【Dubbo】dubbo使用中遇到的问题 174 【Zookeeper】zookeeper介绍 178 1、简介 178 2、基本概念 179 3. ZooKeeper典型应用场景 183 4、ZooKeeper在大型分布式系统中的应用 ...

    java面试问题汇总(非常全面)

    - `sleep` 方法是 Thread 类的方法,不会释放锁。 #### 14. final和finally,finalize的区别 - **final**:修饰类、方法或变量,表示不可变。 - **finally**:在 try-catch-finally 结构中使用,无论是否出现异常...

    平安银行测试工程师笔试题.pdf

    10. sleep()和wait()的区别是,sleep()方法是Thread类的方法,用于使当前线程进入休眠状态,而wait()方法是Object类的方法,用于使当前线程等待其他线程的通知。 11. 以下哪行代码会进行对象垃圾回收是第7行。因为...

    MySQL为什么要避免大事务以及大事务解决的方法

    MySQL数据库在处理事务时,尤其是大事务,需要特别注意其对系统性能和并发能力的影响。大事务通常指的是运行时间较长、涉及大量数据修改或锁定较多资源的事务。由于这些特性,大事务可能导致一系列问题,包括但不...

    jedis使用指南

    Thread.sleep(3, r.nextInt(500)); } } catch (Exception e) { } return false; } public boolean lock() { return lock(DEFAULT_TIME_OUT); } // 无论是否加锁成功,必须调用 public void unlock() { ...

    java 线程 基础

    通过 `Thread.sleep(time)` 方法,线程会被挂起指定的毫秒数。`main` 方法创建了三个 `Thread` 对象并启动,使得它们并发执行。`MyThread` 的 `info()` 方法用于在主线程中打印信息。 第二个编程题涉及银行取款和...

    net学习笔记及其他代码应用

    使用QueryString, 如....?id=1; response. Redirect().... 2.使用Session变量 3.使用Server.Transfer 3. 一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。 答:...

    杭州端点公司java面试题.md

    - `Thread.sleep()` 不需要同步锁,而 `Object.wait()` 必须在同步上下文中调用,并释放锁。 **13. MySql中的索引** - **索引底层实现原理**: - MySQL 使用 B+Tree 结构存储索引。 - B+Tree 允许快速查找、插入...

    JAVA相关的面试大全

    - `sleep()`是`Thread`类的方法,使当前线程暂停指定时间。 - `wait()`是`Object`类的方法,使线程等待直至被唤醒。 #### 14. Overload和Override的区别 - **Overload**:方法重载,同一个类中的多个同名方法,...

    某大型通讯企业内部Java岗笔试题.docx

    每个任务应具有独立事务,失败不影响其他成功任务。D描述了超时处理,是正确的。A和B可能不适用于有顺序依赖的场景,C是正确的并发调用特性。 8. Kafka的消费模式:Kafka的消费模型基于消费组(GroupId)。同一...

    tps java测试代码.txt

    这是在调用`Thread.sleep()`等阻塞方法时可能会抛出的异常。 - 异常处理对于编写健壮的并发程序至关重要。适当的异常处理可以避免程序因意外错误而崩溃,并提供错误恢复的机会。 #### 6. **打印结果分析** - 最后...

    prograssbar動態增加

    Thread.Sleep(100); // 控制更新频率 } } ``` 通过以上步骤,我们成功地结合了C#、SQLDMO和进度条控件,实现了在后台备份SQL Server数据库并实时显示备份进度的功能。在实际开发中,应根据项目的具体需求调整...

Global site tag (gtag.js) - Google Analytics