View difference between Paste ID: rkv9N7SQ and uW4hDbvM
SHOW: | | - or go back to the newest paste.
1
<?php
2
/**
3
  
4
  Нужно поднять 2 инстанса базы и в обоих создать базу:
5
  
6
  create table some_table (id int(10) NOT NULL AUTO_INCREMENT, `field` varchar(255) not null, `value` varchar(255), PRIMARY KEY (`id`)) type = InnoDB;
7
  
8
  Запускаем скрипт, скрипт останавливается ожидая ввода пользователя. останавливаем один сервер, нажимаем Enter (2 раза)
9
10
 */
11
12
13
function waitUser() {
14
  echo "Sleep. Press enter...\n";
15
  $line = trim(fgets(STDIN));
16
  fscanf(STDIN, "\n"); 
17
  echo "Done. Commiting.\n";
18
}
19
20
class MysqlConnect
21
{
22
23
  protected $link = null;
24
  protected $host = null;
25
26
  public function __construct($host, $database, $username, $password)
27
  {
28
    $this->host = $host;
29
    $this->link = mysql_connect($host, $username, $password, true);
30
    mysql_select_db($database, $this->link);
31
  }
32
  
33
  private function log($message) {
34
    echo "[{$this->host}] {$message}\n";
35
  }
36
37
  public function query($query)
38
  {
39
    $this->log($query);
40
    $res = mysql_query($query, $this->link) or $this->log("ERROR: " . mysql_error());
41
42
    return $res;
43
  }
44
45
  public function fetchAll($query)
46
  {
47
    $res = $this->query($query);
48
49
    $result = array();
50
    while ($row = mysql_fetch_assoc($res)) {
51
      $result[] = $row;
52
    }
53
    return $res;
54
  }
55
56
  public function insert($table, $data)
57
  {
58
    if (!count($data))
59
      return false;
60
61
    list($row) = $data;
62
    $cols = array();
63
    foreach ($row as $key => $value) {
64
      $cols[] = $key;
65
    }
66
    $cols = implode(", ", $cols);
67
68
    $values = array();
69
    foreach ($data as $row) {
70
      $values[] = "'" . implode("', '", $row) . "'";
71
    }
72
73
    $values = "(" . implode("), (", $values) . ")";
74
75
    $query = "INSERT INTO `{$table}` ($cols) VALUES {$values}";
76
    
77
    $this->query($query);
78
  }
79
}
80
81
class ConnectManager
82
{
83
  protected $connections = array();
84
  protected $firstConnection = null;
85
  
86
  protected $lastTxId = null;
87
  
88
  public function __construct($connections) 
89
  {
90
    $this->connections = $connections;
91
    $this->firstConnection = array_shift($connections);
92
  }
93
  
94
  public function query($query) 
95
  {
96
    foreach ($this->connections as $connection) {
97
      $connection->query($query);
98
    }
99
  }
100
  
101
  public function fetchAll($query) 
102
  {
103
    foreach ($this->connections as $connection) {
104
      $connection->fetchAll($query);
105
    }
106
  }
107
  
108
  public function insert($table, $data) 
109
  {
110
    foreach ($this->connections as $connection) {
111
      $connection->insert($table, $data);
112
    }
113
  }
114
  
115
  protected function getTxIdent() 
116
  {
117
    return uniqid("tx-", true);
118
  }
119
  
120
  public function txBegin() 
121
  {
122
    $tid = $this->getTxIdent();
123
    $this->lastTxId = $tid;
124
    foreach ($this->connections as $connection) {
125
      $connection->query("XA START '{$tid}'");
126
    }
127
  }
128
  
129
  public function txCommit() 
130
  {
131
    $tid = $this->lastTxId;
132
    foreach ($this->connections as $connection) {
133
//    $connection = $this->firstConnection;
134
      $connection->query("XA END '{$tid}'");
135
      $connection->query("XA PREPARE '{$tid}'");
136
    }
137
    
138
    waitUser();
139
    
140
    foreach ($this->connections as $connection) {
141
      $connection->query("XA COMMIT '{$tid}'");
142
    }
143
  }
144
  
145
  public function txRollback() 
146
  {
147
    $tid = $this->lastTxId;
148
    foreach ($this->connections as $connection) {
149
      $connection->query("XA END '{$tid}'");
150
      $connection->query("XA RALLBACK '{$tid}'");
151
    }
152
  }
153
  
154
}
155
156
$int = rand(0, 999);
157
echo "LAST INT: {$int}\n";
158
159
$c1 = new MysqlConnect("localhost", "xa_test", "user", "password");
160
$c2 = new MysqlConnect("192.168.56.10", "xa_test", "user", "password");
161
162
$man = new ConnectManager(array($c1, $c2));
163
$man->txBegin();
164
165
$i = $int;
166
$c1->insert("some_table", array(array("field" => "field {$i}", "value" => rand(0, 999))));
167
$c2->insert("some_table", array(array("field" => "field {$i}", "value" => rand(0, 999))));
168
169
$man->txCommit();