package com.lock;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.CountDownLatch;
public class LostUpdateOccDiscard implements Runnable{
private CountDownLatch countDown;
public LostUpdateOccDiscard(CountDownLatch countDown){
this.countDown = countDown;
}
@Override
public void run() {
Connection conn=null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager
.getConnection(
"jdbc:mysql://192.168.1.191:3306/fangwifi_new?useUnicode=true&characterEncoding=UTF-8",
"root", "kw2014_!)");
} catch (Exception e) {
e.printStackTrace();
return;
}
try {
conn.setAutoCommit(false);
//读的时候一并读出version
PreparedStatement ps =conn.prepareStatement("select * from LostUpdate where id =1");
ResultSet rs=ps.executeQuery();
int count = 0;
int version = 0;
while(rs.next()){
count= rs.getInt("count");
version= rs.getInt("version");
}
count++;
//更新操作,用cas原子操作来更新
ps =conn.prepareStatement("update LostUpdate set count=?, version=version+1 where id =1 and version=?");
ps.setInt(1, count);
ps.setInt(2, version);
int result = ps.executeUpdate();
//检查有无因冲突导致执行失败
//成功,则commit,完成任务
if(result>0) {
conn.commit();
}
//失败,回滚,抛异常提醒调用者出现冲突。
else{
conn.rollback();
throw new Exception("更新count出现冲突");
}
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
catch (Exception e) {
System.out.println(e.getMessage());
}
//表示一次任务完成
countDown.countDown();
}
}
package com.lock;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestLockOcc {
public static void main(String[] args) throws InterruptedException {
//创建线程池,里面有10个线程,共执行100次+1操作
final int THREAD_COUNT=10;
final int RUN_TIME=100;
ExecutorService threadPool=Executors.newFixedThreadPool(THREAD_COUNT);
//用CountDownLatch保证主线程等待所有任务完成
CountDownLatch count=new CountDownLatch(RUN_TIME);
for(int i=0;i threadPool.execute(new LostUpdateOccDiscard(count));
threadPool.shutdown();
count.await();
//提示所有任务执行完
System.out.println("finish");
}
}
package com.lock;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.CountDownLatch;
public class LostUpdateOccDiscard implements Runnable{
private CountDownLatch countDown;
public LostUpdateOccDiscard(CountDownLatch countDown){
this.countDown = countDown;
}
@Override
public void run() {
Connection conn=null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager
.getConnection(
"jdbc:mysql://192.168.1.191:3306/fangwifi_new?useUnicode=true&characterEncoding=UTF-8",
"root", "kw2014_!)");
} catch (Exception e) {
e.printStackTrace();
return;
}
try {
conn.setAutoCommit(false);
//读的时候一并读出version
PreparedStatement ps =conn.prepareStatement("select * from LostUpdate where id =1");
ResultSet rs=ps.executeQuery();
int count = 0;
int version = 0;
while(rs.next()){
count= rs.getInt("count");
version= rs.getInt("version");
}
count++;
//更新操作,用cas原子操作来更新
ps =conn.prepareStatement("update LostUpdate set count=?, version=version+1 where id =1 and version=?");
ps.setInt(1, count);
ps.setInt(2, version);
int result = ps.executeUpdate();
//检查有无因冲突导致执行失败
//成功,则commit,完成任务
if(result>0) {
conn.commit();
}
//失败,回滚,抛异常提醒调用者出现冲突。
else{
conn.rollback();
throw new Exception("更新count出现冲突");
}
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
catch (Exception e) {
System.out.println(e.getMessage());
}
//表示一次任务完成
countDown.countDown();
}
}
转载至https://www.cnblogs.com/deliver/p/5730616.html