1.以G71列車為例,首先對車次站台進行占位編碼(從1開始到最后一站遞加)

對以上占位簡單描述以下:G71總共18個站點那么我們的單個座位的座位標識可以用十八位長度的二進制字符串表示10000000000000000每一位代表一個站點,每天放票前初始化到下面的訂票表中,數據如下余票根據座位標識中的0的個數決定最大余票數量

訂票表中的始發受限站點和終到受限站點可以靈活搭配(這個就可以實現限制站點發售)
限售渠道十進制 7 代表 1(車站)| 2(互聯網)|4(電話)=7 即該票允許 車站, 互聯網, 電話同時出售
那么還可以是 1|4 = 5 即該票只接受在車站和電話預定
擴展 8(代售點) 16 (手機端)
2.查詢余票
如果我們要用互聯網渠道查詢日期為2016-06-11,始發站保定東站(3)到韶關站(15)的G71二等座F座位余票情況只需要執行如下sql(該SQL可以實現選座位和選車廂等功能)
select GUID,車次編碼,車次類型,座位類型,車廂號碼,座位編碼,座位位置,車票版本號 from 訂票表 where 座位標識=~((~坐標標識)|000111111111111000) and 發車日期='2016-06-11' and 車次編碼='G71' and 始發受限車站=始發受限車站|000100000000000000 and 終到受限車站=終到受限車站|000000000000001000 and 車次類型='二等座' and 座位位置='F'
and 受限渠道=2|受限渠道
order by 余票數量 asc ,車廂 asc --先賣余票少的,防止打亂更多的長途票
3.預定票
3.1根據第二步中查詢條件獲取一條記錄然后將車票狀態改為鎖定
3.2待鎖定成功后進行支付
update 訂票表 set 座位標識=座位標識 | 000111111111111000,車票版本號=車票版本號+1,余票數量 = 余票數量-(15-3) where GUID = Md5(車次+座位編碼+發車日期) and 座位標識=~((~坐標標識)|000111111111111000)--樂觀鎖 根據更新結果是否為1則可以判定購票成功
3.2支付成功后然后將保定到韶關的票保存到另外一張客戶的車票表中
3.3如果指定時間沒有支付,那么直接調用退票sql
4.退票
獲得該車次保定到韶關的票 (000111111111111000)與對應的票進行異或^運算,則即可回歸票池子了
5.選座
update 訂票表 set 座位標識=座位標識 ^000111111111111000,余票數量 = 余票數量+(15-3),車票版本號=車票版本號+1 where GUID = Md5(車次+座位編碼+發車日期) and 車票版本號=取得的版本號 --樂觀鎖
根據返回結果為1則標識退票成功
以下為相關java代碼
1 import java.math.BigDecimal; 2 3 public class MainTest { 4 public static void main(String[] args) { 5 String ticketFlag = "100000000000000000"; 6 int beginStation = 3; 7 int endStation = 15; 8 long beginTime = System.currentTimeMillis(); 9 String result = orderTicket(ticketFlag, beginStation, endStation); 10 if (result.equals(ticketFlag)) { 11 System.out.println("訂票失敗"); 12 } else { 13 System.out.println("訂票后的結果:" + result); 14 // 如果要取消的話,就進行這個操作 15 String b = buildTicket(ticketFlag.length(), beginStation, 16 endStation); 17 System.out.println("釋放后的結果:" + releaseTicket(ticketFlag, b)); 18 19 } 20 long endTime = System.currentTimeMillis(); 21 System.out.println("耗時:" + (endTime - beginTime)); 22 } 23 24 /** 25 * 訂票 26 * 27 * @param ticketFlag 28 * @param beginStation 29 * @param endStation 30 * @return 31 */ 32 private static String orderTicket(String ticketFlag, int beginStation, 33 int endStation) { 34 String result = ""; 35 if (checkCanTicket(ticketFlag, beginStation, endStation)) { 36 String b = buildTicket(ticketFlag.length(), beginStation, 37 endStation); 38 39 String currentTicked = toTicket(ticketFlag, b); 40 System.out.println("預占票前結果:" + ticketFlag); 41 result = currentTicked; 42 } else { 43 result = ticketFlag; 44 } 45 ; 46 return result; 47 } 48 49 /** 50 * 取消已定票 51 * 52 * @param ticketFlag 53 * @param b 54 * @return 55 */ 56 private static String releaseTicket(String ticketFlag, String b) { 57 StringBuilder tempSt = new StringBuilder(""); 58 int length = ticketFlag.length(); 59 for (int i = 0; i < length; i++) { 60 char tempA = ticketFlag.charAt(i); 61 char tempB = b.charAt(i); 62 if (tempA == '1' && tempB == '1') { 63 tempSt.append("0"); 64 } else { 65 tempSt.append(tempA); 66 } 67 } 68 return tempSt.toString(); 69 } 70 71 /** 72 * 創建區間占位票 73 * 74 * @param length 75 * @param beginStation 76 * @param endStation 77 * @return 78 */ 79 private static String buildTicket(int length, int beginStation, 80 int endStation) { 81 StringBuilder st = new StringBuilder(""); 82 for (int i = 0; i < length; i++) { 83 if (i >= beginStation && i < endStation) { 84 st.append("1"); 85 } else { 86 st.append("0"); 87 } 88 } 89 System.out.println("創建區間票:" + st.toString()); 90 return st.toString(); 91 } 92 93 /** 94 * 生成訂票后的結果 95 * 96 * @param ticketFlag 97 * @param b 98 * @return 99 */ 100 private static String toTicket(String ticketFlag, String b) { 101 StringBuilder tempSt = new StringBuilder(""); 102 int length = ticketFlag.length(); 103 for (int i = 0; i < length; i++) { 104 char tempA = ticketFlag.charAt(i); 105 char tempB = b.charAt(i); 106 if (tempA == '1' || tempB == '1') { 107 tempSt.append("1"); 108 } else { 109 tempSt.append(tempA); 110 } 111 } 112 return tempSt.toString(); 113 } 114 115 /** 116 * 是否可以訂票 117 * 118 * @param ticketFlag 119 * @param beginStation 120 * @param endStation 121 * @return 122 */ 123 private static boolean checkCanTicket(String ticketFlag, int beginStation, 124 int endStation) { 125 boolean result = false; 126 String tempTicket = ticketFlag.substring(beginStation, endStation); 127 BigDecimal b = new BigDecimal(tempTicket); 128 if (b.equals(new BigDecimal("0"))) { 129 result = true; 130 } 131 return result; 132 } 133 134 }

本文原創:轉載請注明出處 http://www.cnblogs.com/feichengwurao/p/5191253.html
