2016-08-02 5 views
1

Ich muss nicht gleichzeitig mit dem gleichen Bestätigungscode in meiner Spring/OpenJPA 1-Anwendung arbeiten zulassen. Wir haben uns dafür entschieden, select für die Update-Strategie zu verwenden, also haben wir die Tabelle AdmissionLock (id, Confirmation_Code, Terminal) erstellt.
Die separate JDBC-Beispielanwendung funktioniert problemlos mit dieser Strategie. Es ermöglicht die gleichzeitige Verarbeitung verschiedener Bestätigungscodes und erlaubt nicht die gleichzeitige Verarbeitung derselben Bestätigungscodes. Bitte finden Sie in dem folgenden Beispielcode:So erstellen Sie eine Auswahl für die Aktualisierung der Zeilensperre in Spring/OpenJPA 1

Thema Code:

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

Hauptprogrammcode:

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=?;";   

Seit unserer Anwendung ist Frühjahr/OpenJPA 1 Ich muss diese Idee in Spring/OPenJPA 1 Code integrieren. Also, habe ich den Dienst mit diesem vereinfachten Code:

@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:

@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"; 
... 
} 

Mein Problem ist, dass dieser Code hat nichts sperren. Beide simultanen Threads mit dem gleichen Bestätigungscode durchlaufen

Antwort

0

Ich endete mit den gleichen nativen Abfragen wie in der JDBC-Anwendung. Ein wichtiger Unterschied - Starten der Transaktion ("START TRANSACTION") und Commit ("COMMIT") werden zu MYSQL selbst verschoben und von der JDBC executeUpdate() -Methode aufgerufen.

Verwandte Themen