Guest User

Untitled

a guest
Jun 6th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.07 KB | None | 0 0
  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7. import java.util.concurrent.Callable;
  8. import java.util.concurrent.ExecutorService;
  9. import java.util.concurrent.Executors;
  10. import java.util.concurrent.Future;
  11. import java.util.concurrent.TimeUnit;
  12.  
  13. public class TT {
  14.  
  15. private static final String url = "jdbc:postgresql://localhost/postgres?user=postgres&password=q";
  16.  
  17. private static final String SQL_SETUP_CONTEXT =
  18. "DROP TABLE IF EXISTS accounts;"+"\n"+
  19. "CREATE TABLE accounts(id int, amount int);"+"\n"+
  20. "INSERT INTO accounts VALUES(1,100);"+"\n"+
  21. "INSERT INTO accounts VALUES(2,100)";
  22.  
  23. private static final String SQL_AMOUNT_DEDUCTING_FUNCTION =
  24. "CREATE OR REPLACE FUNCTION test (id1 int, id2 int) RETURNS boolean AS $$"+"\n"+
  25. "BEGIN"+"\n"+
  26. //"\tUPDATE accounts SET amount=amount WHERE id IN (id1,id2);"+"\n"+
  27. //"\tUPDATE accounts SET amount=amount WHERE id=id2;"+"\n"+
  28. "\tIF (SELECT SUM(amount) FROM accounts WHERE id IN (id1,id2)) >= 0 THEN"+"\n"+
  29. "\t\tUPDATE accounts SET amount=amount-200 WHERE id=id1;"+"\n"+
  30. "\t\tRETURN true;"+"\n"+
  31. "\tEND IF;"+"\n"+
  32. "\tRETURN false;"+"\n"+
  33. "END;"+"\n"+
  34. "$$ LANGUAGE plpgsql;";
  35.  
  36. private static final String SQL_UPDATE_AMOUNTS =
  37. "UPDATE accounts SET amount = 100";
  38.  
  39. private static final String SQL_GET_AMOUNTS =
  40. "SELECT amount FROM accounts ORDER BY id";
  41.  
  42. private static final String SQL_DEDUCT_AMOUNT =
  43. "START TRANSACTION ISOLATION LEVEL SERIALIZABLE;"+"\n"+
  44. "SELECT * FROM test(?,?);"+"\n"+
  45. "END TRANSACTION;";
  46.  
  47.  
  48. public static void main(String[] args) {
  49. try {
  50. Class.forName("org.postgresql.Driver");
  51. } catch (ClassNotFoundException e) {
  52. e.printStackTrace();
  53. return;
  54. }
  55.  
  56. Connection conn = null;
  57. try {
  58. conn = DriverManager.getConnection(url);
  59. } catch (SQLException e) {
  60. e.printStackTrace();
  61. return;
  62. }
  63. Statement stmt = null;
  64. try{
  65. stmt = conn.createStatement();
  66. }
  67. catch(SQLException e){
  68. e.printStackTrace();
  69. try {
  70. conn.close();
  71. } catch (SQLException e1) {
  72. e1.printStackTrace();
  73. }
  74. return;
  75. }
  76.  
  77. try {
  78. stmt.execute(SQL_SETUP_CONTEXT);
  79. stmt.execute(SQL_AMOUNT_DEDUCTING_FUNCTION);
  80.  
  81. Callable<Boolean> deductMoneyFromAccnt1 = new Callable<Boolean>() {
  82. @Override
  83. public Boolean call() {
  84. return deductMoneyFromAccount(1,2);
  85. }
  86. };
  87. Callable<Boolean> deductMoneyFromAccnt2 = new Callable<Boolean>() {
  88. @Override
  89. public Boolean call() {
  90. return deductMoneyFromAccount(2,1);
  91. }
  92. };
  93. ExecutorService e = Executors.newFixedThreadPool(2);
  94.  
  95. int cnt=0;
  96. while(cnt++ < 10){
  97. stmt.executeUpdate(SQL_UPDATE_AMOUNTS);
  98.  
  99. Future<Boolean> futureAccnt1 = e.submit(deductMoneyFromAccnt1);
  100. Future<Boolean> futureAccnt2 = e.submit(deductMoneyFromAccnt2);
  101.  
  102. try {
  103. futureAccnt1.get();
  104. futureAccnt2.get();
  105. } catch (Exception e1) {
  106. e1.printStackTrace();
  107. }
  108.  
  109. ResultSet rs = stmt.executeQuery(SQL_GET_AMOUNTS);
  110. rs.next(); int amount1 = rs.getInt(1);
  111. rs.next(); int amount2 = rs.getInt(1);
  112. System.out.println("Amounts=["+amount1+","+amount2+"]\n");
  113. rs.close();
  114. }
  115.  
  116. e.shutdown();
  117.  
  118. } catch (SQLException e) {
  119. e.printStackTrace();
  120. }
  121. finally {
  122. try {
  123. stmt.close();
  124. conn.close();
  125. } catch (SQLException e) {
  126. e.printStackTrace();
  127. }
  128. }
  129. }
  130.  
  131. private static Boolean deductMoneyFromAccount(int id1, int id2){
  132. /*try {
  133. TimeUnit.MILLISECONDS.sleep((id1 - 1) * 5);
  134. } catch (InterruptedException e1) {
  135. e1.printStackTrace();
  136. }*/
  137. Connection conn = null;
  138. PreparedStatement pstmt = null;
  139. try {
  140. conn = DriverManager.getConnection(url);
  141. pstmt = conn.prepareStatement(SQL_DEDUCT_AMOUNT);
  142. pstmt.setInt(1, id1);
  143. pstmt.setInt(2, id2);
  144. boolean r = pstmt.execute();
  145. return r;
  146. } catch (SQLException e) {
  147. System.out.println("Deducting from account="+id1+" gave "+e.getMessage());
  148. }
  149. finally{
  150. try {
  151. pstmt.close();
  152. conn.close();
  153. } catch (SQLException e) {
  154. e.printStackTrace();
  155. }
  156. }
  157. return null;
  158. }
  159.  
  160. }
Add Comment
Please, Sign In to add comment