2016-08-02 18 views
1

我需要在Spring/OpenJPA 1應用程序中不允許同時使用相同的確認代碼。我們決定使用select來更新策略,所以我們創建了表AdmissionLock(id,Confirmation_Code,Terminal)。
單獨的示例JDBC應用程序可以很好地與此策略配合使用。它允許同時處理不同的確認碼,並且不允許同時處理相同的確認碼。請參閱下面的示例代碼:如何在Spring/OpenJPA 1中重新創建select更新行鎖定1

線程代碼:

conn.setAutoCommit(false); 
long retId = Util.lockBySelectUpdate(conn, threadName, terminalCode, confNumber); 
Util.updateConfCode(conn, threadName, terminalCode, confNumber); 
conn.commit(); 

主程序代碼:

String confCode1 = "21"; 
String confCode2 = "22"; 
String terminalCode1 = "10"; 
String terminalCode2 = "11"; 
Connection conn1 = Util.getNewConnection(); 
Connection conn2 = Util.getNewConnection(); 
AdmissionThread admissionThread1=new AdmissionThread(terminalCode1, conn1, confCode1, "Thread1", 10); 
AdmissionThread admissionThread2=new AdmissionThread(terminalCode2, conn2, confCode2, "Thread2", 0); 
    admissionThread1.start(); 
    Thread.sleep(2000); 
    admissionThread2.start(); 

SQL:

"SELECT * FROM ADMISSIONLOCK WHERE CONFIRMATION_CODE=? FOR UPDATE" 

"update ADMISSIONLOCK set CONFIRMATION_CODE=? where TERMINAL_SERIAL_NUMBER=?;";   

由於我們的應用程序是春/ OpenJPA的1我需要在Spring/OPenJPA 1代碼中加入這個想法。所以,我創建了這個簡化代碼的服務:

@Transactional 
public void processAdmissionLock (String terminalSerialNumber, String confirmationCode){ 

AdmissionLock admissionLock = new AdmissionLock(terminalSerialNumber, confirmationCode); 
     query = entityManager.createNativeQuery(SQL_LOCK_STRING); 
     entityManager.lock(admissionLock, LockModeType.READ); 
     query.setParameter(1, confirmationCode).getResultList(); 

     if(isEntityPersistent(admissionLock)) { 
      admissionLock = entityManager.merge(admissionLock); 
     } else { 
      entityManager.persist(admissionLock); 
     } 
} 

AdmissionLock實體:

@Entity 
@Table (name = SdiAdmissionLock.TABLE_NAME) 
public class SdiAdmissionLock extends AbstractEntityImpl { 

    private static final long serialVersionUID = 1L; 
    private long uidpk; 
    private String terminalSerialNumber; 
    private String confirmationCode; 
    private Date createdDate; 

    public static final String TABLE_NAME = "SDIADMISSIONLOCK"; 
... 
} 

我的問題是,這個代碼不作任何鎖定。兩個具有相同驗證碼的同時線程都通過

回答

0

我最終使用了與JDBC應用程序中相同的本機查詢。一個重要的區別 - 起始事務(「START TRANSACTION」)和提交(「COMMIT」)被轉移到MYSQL本身並由JDBC executeUpdate()方法調用。