java模拟死锁_java死锁模拟

该博客通过两个并发执行的 Java 测试类 `JDBCExample` 和 `JDBCExample1`,模拟了数据库死锁的情况。每个测试类中,先更新了一条记录的 `scheme_id`,然后尝试更新另一条记录。由于并发执行时两条更新语句的顺序不同,导致了死锁。在执行过程中,MySQL 抛出了 `Deadlock found when trying to get lock; try restarting transaction` 的异常,说明了死锁的存在。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecn.tk.netcore.rest;importlombok.extern.slf4j.Slf4j;importorg.junit.Test;importorg.junit.runner.RunWith;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.test.context.junit4.SpringRunner;import java.sql.*;

@SpringBootTest

@RunWith(SpringRunner.class)

@Slf4jpublic classJDBCExample {//第二步:说明JDBC驱动的名称和数据库的地址

static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";static final String DB_URL = "jdbc:mysql://ip:port/tktop";//第三步:说明数据库的认证账户及密码

static final String USER = "user";static final String PASS = "password";

@Testpublic voidjsbcTest() {//第四步:注册JDBC驱动

try{

Class.forName(JDBC_DRIVER);

}catch(ClassNotFoundException e) {//这里会发生类没有找到的异常!

e.printStackTrace();

}//第五步:获得数据库连接

try{

Connection connection=DriverManager.getConnection(DB_URL,USER,PASS);//设置手动提交

connection.setAutoCommit (false);

Statement statement=connection.createStatement();//第六步:执行修改语句

String sql = "UPDATE s_policymain s set s.scheme_id = '1' where s.policy_no = '123781628736178321'";

statement.executeUpdate (sql);//第七步:执行修改语句

String sql1 = "UPDATE s_policymain s set s.scheme_id = '2' where s.policy_no = '200323008677720117840'";

statement.executeUpdate(sql1);

statement.close();

connection.close();

}catch(SQLException e) {

e.printStackTrace();//这里会发生SQL异常,因为我们提供的的账户和密码不一定能连接成功

}

}

}

View Code

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecn.tk.netcore.rest;importlombok.extern.slf4j.Slf4j;importorg.junit.Test;importorg.junit.runner.RunWith;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.test.context.junit4.SpringRunner;import java.sql.*;

@SpringBootTest

@RunWith(SpringRunner.class)

@Slf4jpublic classJDBCExample1{//第二步:说明JDBC驱动的名称和数据库的地址

static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";static final String DB_URL = "jdbc:mysql://ip:port/tktop";//第三步:说明数据库的认证账户及密码

static final String USER = "user";static final String PASS = "password";

@Testpublic voidjsbcTest() {//第四步:注册JDBC驱动

try{

Class.forName(JDBC_DRIVER);

}catch(ClassNotFoundException e) {//这里会发生类没有找到的异常!

e.printStackTrace();

}//第五步:获得数据库连接

try{

Connection connection=DriverManager.getConnection(DB_URL,USER,PASS);//设置手动提交

connection.setAutoCommit (false);

Statement statement=connection.createStatement();//第六步:执行修改语句

String sql1 = "UPDATE s_policymain s set s.scheme_id = '2' where s.policy_no = '200323008677720117840'";

statement.executeUpdate (sql1);//第七步:执行修改语句

String sql = "UPDATE s_policymain s set s.scheme_id = '1' where s.policy_no = '123781628736178321'";

statement.executeUpdate(sql);//第七步:关闭连接资源

statement.close();

connection.close();

}catch(SQLException e) {

e.printStackTrace();//这里会发生SQL异常,因为我们提供的的账户和密码不一定能连接成功

}

}

}

View Code

执行步骤:

1,执行 JDBCExample的第六步,

2,执行JDBCExample1的第六步,

3,执行 JDBCExample的第七步,

4,执行 JDBCExample1的第七步,

报出死锁异常:

com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)

at com.mysql.jdbc.Util.getInstance(Util.java:408)

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:952)

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3933)

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3869)

at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)

at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2675)

at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2465)

at com.mysql.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1536)

at com.mysql.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2585)

at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1464)

at cn.tk.netcore.rest.JDBCExample1.jsbcTest(JDBCExample1.java:45)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)

at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)

at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)

at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)

at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)

at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)

at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)

at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)

at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)

at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)

at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)

at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值